#!/bin/bash

#
# osxnet -- by Dario Berzano <dario.berzano@gmail.com>
#
# Part of the lfscripts suite -- http://lfscripts.googecode.com/
#
# Wrapper to easily control some OS X network services.
#
# Parts inspired by http://hints.macworld.com/dlfiles/network_service_name.txt.
#

# Help screen
function PrintHelp() {
  cat <<_EOF_
$Prog -- by Dario Berzano <dario.berzano@cern.ch>
Shortcut to control OS X proxy and other network functions via command line.

Usage: $Prog [options] [libraries...]
    -t, --toggleproxy on|off         turns proxy on or off for current location
    -s, --setproxy HOST:PORT         sets proxy
    -p, --print                      print current proxy settings
    -n, --getnet                     get current OS X network location
    -w, --whatismyip                 opens default browser to IP telling service
    -h, --help                       this help screen
_EOF_
}

# Returns the name of the active network service, or an empty string if no
# service is active (offline) or any error occured
function GetActiveNetworkService() {

  local Raw ServiceId ServiceName

  Raw=`scutil <<EOF
open
get State:/Network/Global/IPv4
d.show
EOF`
  ServiceId=`echo "$Raw" | \
    perl -ne '/PrimaryService\s*:\s*([A-Z0-9-]+)/ and print "$1\n"'`

  Raw=`scutil <<EOF
open
get Setup:/Network/Service/$ServiceId
d.show
EOF`

  ServiceName=`echo "$Raw" | \
    perl -ne '/UserDefinedName\s*:\s*(.+)$/ and print "$1\n"'`

  echo $ServiceName

}

# Main function
function Main() {

  local Args Prog

  if [ `uname` != 'Darwin' ] ; then
    echo 'Sorry, this script only works on Mac OS X, exiting.' >&2
    exit 1
  fi

  # A decent version of getopt is required! Do port install getopt...
  Prog=`basename "$0"`
  Args=`getopt -o 't:s:npwh' \
    --long 'toggleproxy:setproxy:getnet,print,help,whatismyip' \
    -n "$Prog" -- "$@"`
  [ $? != 0 ] && exit 1
  eval set -- "$Args"

  local ActiveNs
  local ProxyState GetNet ProxyHostPort ProxyPrint MyIp

  while [ "$1" != '--' ] ; do

    case "$1" in

      --toggleproxy|-t)
        ProxyState=`echo "$2" | tr '[:upper:]' '[:lower:]'`
        shift 2
      ;;

      --setproxy|-s)
        ProxyHostPort="$2"
        shift 2
      ;;

      --print|-p)
        ProxyPrint=1
        shift 1
      ;;

      --getnet|-n)
        GetNet=1
        shift 1
      ;;

      --whatismyip|-w)
        MyIp=1
        shift 1
      ;;

      --help|-h)
        PrintHelp
        return 1
      ;;

    esac

  done

  shift # --
  #echo "Remaining: $@"

  # Always get active network service
  ActiveNs=`GetActiveNetworkService`

  # Turn web proxy on/off
  if [ "$ProxyState" != '' ] ; then

    if [ "$ActiveNs" == '' ] ; then
      echo "$Prog: no active network service (are you offline?), exiting" >&2
      exit 1
    fi

    if [ "$ProxyState" != 'on' ] && [ "$ProxyState" != 'off' ] ; then
      echo "$Prog: proxy state can be on/off" >&2
    else
      networksetup -setwebproxystate "$ActiveNs" $ProxyState &> /dev/null && \
      networksetup -setsecurewebproxystate "$ActiveNs" $ProxyState &> /dev/null
      if [ $? == 0 ] ; then
        echo "$Prog: HTTP/HTTPS proxies set to $ProxyState" >&2
      else
        echo "$Prog: error setting HTTP/HTTPS proxies state" >&2
      fi
    fi

  fi

  # Set web proxy to host:port
  if [ "$ProxyHostPort" != '' ] ; then

    ProxyHost=${ProxyHostPort%:*}
    ProxyPort=${ProxyHostPort##*:}

    if [ "$ProxyHost" == "$ProxyHostPort" ] ; then
      echo "$Prog: please specify proxyhost:port in this format" >&2
    else
      networksetup -setwebproxy "$ActiveNs" $ProxyHost $ProxyPort && \
      networksetup -setsecurewebproxy "$ActiveNs" $ProxyHost $ProxyPort
      if [ $? == 0 ] ; then
        echo "$Prog: HTTP/HTTPS proxy set to $ProxyHost (port $ProxyPort)" >&2
      else
        echo "$Prog: error setting HTTP/HTTPS proxy host and port" >&2
      fi
    fi

  fi

  # Print out network service
  if [ "$GetNet" != '' ] ; then
    echo "$ActiveNs"
  fi

  # Print out proxy stattes
  if [ "$ProxyPrint" != '' ] ; then
    if [ "$ActiveNs" != '' ] ; then
      echo "Active network service: $ActiveNs"
      echo '--> Configuration for HTTP'
      networksetup -getwebproxy "$ActiveNs"
      echo '--> Configuration for HTTPS'
      networksetup -getsecurewebproxy "$ActiveNs"
    else
      echo "$Prog: can't print configuration, no network service active" >&2
    fi
  fi

  # Connect to whatismyip.org
  if [ "$MyIp" != '' ] ; then
    open http://www.whatismyip.org
  fi

}

#
# Entry point
#

Main "$@"
